<template>
    <div id="dev-assistant">
        <el-tabs v-model="activeName" type="card" class="tabs" @tab-change="onTabChange">
            <el-tab-pane label="编辑数据源" name="add-data-source">
                <div class="add-data-source data-source">
                    <div class="data-source-list">
                        <el-tree :data="dataSource" :props="dataSourceProps" />
                    </div>
                    <div class="add-datasource-form">
                        <div class="form-btn">
                            <el-button type="primary" plain @click="addRoww">添加一行</el-button>
                            <el-button @click="importFromResultSet">从结果集中导入</el-button>
                            <!-- <el-button>从SQL中导入</el-button> -->
                            <!-- <el-button>从连接中导入</el-button> -->
                            <el-button type="primary" @click="releaseImport">发布</el-button>
                        </div>
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="代码生成" name="code-generate">
                <div class="data-source data-source-preview">
                    <div class="data-source-list">
                        <el-tree ref="dataSourceTree" :data="dataSource" :props="dataSourceProps" show-checkbox
                            @check="onCheck" />
                    </div>
                    <div class="preview">
                        <div>
                            <div>
                                配置：
                            </div>
                            <el-select v-model="selectedScheme">
                                <el-option v-for="item in templates" :label="item.name" :value="item.id"></el-option>
                            </el-select>
                        </div>
                        <div>
                            <el-checkbox-group v-model="checkedTemplate" v-if="templates && selectedScheme">
                                <el-checkbox v-for="item in templates.find(item => item.id === selectedScheme).templates"
                                    :label="item.content">{{ item.name }}</el-checkbox>
                            </el-checkbox-group>
                        </div>
                        <div>
                            <el-button @click="downloadGenerateFile">下载生成文件</el-button>
                        </div>
                    </div>
                    <div class="fodel_preview">
                        <el-tree :props="fodelTreeProps" node-key="key" :data="fodelTreeData"
                            :default-expanded-keys="expandedKeys" @node-expand="onNodeExpand"
                            @node-collapse="onNodeCollapse" @node-click="onNodeClick" />
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="代码模板" name="code-template">
                <div class="code-template">
                    <div class="header">
                        <div>
                            命名空间：
                        </div>
                        <el-select v-model="selectedScheme">
                            <el-option v-for="item in templates" :label="item.name" :value="item.id"></el-option>
                        </el-select>
                        <el-button @click="doNewNamespace">新增命名空间</el-button>
                        <el-button v-if="selectedScheme" @click="doNewTemplate">新增模板</el-button>
                        <el-button v-if="selectedTemplate" @click="debugCurrentSchemeTemplate">调试</el-button>
                        <el-cascader v-model="debugDataTable" :options="cascaderData" />
                    </div>
                    <div class="content">
                        <div class="scheme">
                            <div class="templateItem" v-if="selectedScheme && templates"
                                v-for="item in templates.find(item => item.id === selectedScheme).templates"
                                @click="changeTemplate(item)" :class="{ selectedTemplate: selectedTemplate == item }">{{
                                    item.name }}
                                <span v-if="item.changed">*</span>
                            </div>
                        </div>
                        <div class="template">
                            <!-- <el-input v-model="currentScheme.template" @input="templateChange"
                                @keydown.tab.native="tabInput($event)" resize="none" type="textarea"
                                :autosize="{ minRows: 30, maxRows: 30 }"></el-input>
                         -->
                            <Codemirror ref="codemirror" v-if="selectedTemplate" v-model:value="selectedTemplate.content"
                                :options="cmOptions" border placeholder="请输入模板内容" :height="640"
                                @change="templateChange(selectedTemplate)">
                            </Codemirror>
                        </div>
                        <div class="tip">
                            <p>#dim 定义变量，如#dim a,b,c</p>
                            <p>#set 变量赋值，如#set a='Hello',b='World'</p>
                            <p>${变量} 取变量内容</p>
                            <p>#for 循环,如 index,value in Range(1,10)</p>
                            <p>#end for 结束for循环</p>
                            <p>#log 记录日志</p>
                        </div>
                    </div>
                </div>
            </el-tab-pane>
        </el-tabs>

        <el-dialog v-model="importFromResultSetDialogVisible" title="从结果集导入">
            <el-form :model="importFromResultSetForm" ref="importFromResultSetForm" :rules="importFromResultSetFormRules">
                <el-form-item label="查询SQL">
                    <el-link @click="copySelectSql">
                        复制
                    </el-link>
                </el-form-item>
                <el-form-item label="命名空间" prop="namespace">
                    <el-select v-model="importFromResultSetForm.namespace" filterable default-first-option allow-create
                        placeholder="选择命名空间" clearable>
                        <el-option v-for="item in namespaceList()" :key="item" :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="数据源" prop="datasource">
                    <el-select v-model="importFromResultSetForm.datasource" filterable default-first-option allow-create
                        placeholder="选择数据源" clearable>
                        <el-option v-for="item in dataSourceList(importFromResultSetForm.namespace)" :key="item" :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="数据库" prop="database">
                    <el-select v-model="importFromResultSetForm.database" filterable default-first-option allow-create
                        placeholder="选择数据库" clearable>
                        <el-option v-for="item in databaseList(importFromResultSetForm.namespace,importFromResultSetForm.datasource)" :key="item"
                            :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="结果集" class="resultSetFormItem" prop="resultSet">
                    <!-- <el-input v-model="importFromResultSetForm.resultSet" :rows="1" clearable type="textarea" placeholder="粘贴结果集" resize="none"/> -->
                    <el-button @click="importResultSetFromClipBoard">从剪切板导入</el-button>
                    <el-link v-if="importFromResultSetForm.resultSet" style="margin-left: 10px;">已导入{{
                        importFromResultSetForm.resultSet.length }}个字段</el-link>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="onImportFromResult">确定导入</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script lang="jsx">
import copy from '@/utils/copy.js'
import {
    getDataScource,
    getTemplates,
    saveTemplate,
    addNamespace,
    addTemplate,
    importDatasource
} from '@/api/devAssistant.js'
import { getDirContent, createZip, render } from '@/puigins/myStringTemplate.js'
import Codemirror from "codemirror-editor-vue3";
import { convertToCamelCase } from '@/utils/object.js'
// theme
import "codemirror/theme/dracula.css";
// placeholder
import "codemirror/addon/display/placeholder.js";
export default {
    data() {
        return {
            // activeName: "data-source",
            activeName: "code-template",
            dataSource: null,
            dataSourceProps: {
                label: 'name',
                children: 'children'
            },
            selectedScheme: null,
            selectedTableData: null,
            dataSourceHeight: 0,
            addDataSourceHeight: 0,
            addDataSourceWidth: 0,
            addDataSourceForm: [],
            databaseCached: [],
            tableCached: [],
            sqlTypeList: ['int', 'bigint', 'varchar', 'date', 'datetime'],
            javaTypeList: ['java.lang.Integer', 'java.util.Date'],
            importFromResultSetDialogVisible: false,
            importFromResultSetForm: {},
            importFromResultSetFormRules: {
                datasource: [{ required: true, message: '请选择数据源' }],
                database: [{ required: true, message: '请选择数据库' }],
                resultSet: [{ required: true, message: '请导入结果集' }],
            },
            templates: {},
            currentTemplateName: '',
            debugDataTable: [],
            checkedTemplate: [],
            fodelTreeProps: {
                label: 'name',
                children: 'children'
            },
            cmOptions: {
                theme: "dracula", // Theme
            },
            selectedTemplate: null,
            expandedKeys: [],
        }
    },
    methods: {
        // updateTreeData(){
        //     let dataSourceTreeSelectedNodes=this.$refs.dataSourceTree.getCheckedNodes()
        //     let selectedTemplates=this.checkedTemplate
        //     console.log(dataSourceTreeSelectedNodes)
        //     console.log(selectedTemplates)
        // },
        expandOnlyOneNodes(b) {
            if (b.childNodes.length === 1) {
                //如果只有一个子节点，则直接展开
                b.childNodes[0].expand()
                this.expandedKeys.push(b.childNodes[0].key)
                this.expandOnlyOneNodes(b.childNodes[0])
            }
        },
        onNodeExpand(a, b, c) {
            console.log(a, b, c)
            this.expandOnlyOneNodes(b)
            this.expandedKeys.push(b.key)
        },
        onNodeCollapse(a, b, c) {
            console.log(b.key, this.expandedKeys)
            for (let i = this.expandedKeys.length - 1; i >= 0; i--) {
                let key = this.expandedKeys[i]
                if (key == b.key || key.startsWith(b.key + "/")) {
                    this.expandedKeys.splice(i, 1)
                }
            }
            return
            let ind = this.expandedKeys.indexOf(b.key)
            if (ind > -1) {
                this.expandedKeys.splice(ind, 1)
            } else {
                console.error("不是预期的值，ind不应该小于0")
            }
        },
        doNewNamespace() {
            this.$prompt('请输入命名空间', '提示', {
                confirmButtonText: '添加',
                cancelButtonText: '取消'
            })
                .then(({ value }) => {
                    addNamespace(value).then(res => {
                        console.log(res)
                        if (res.code == 200) {
                            this.$message.success(res.data)
                            this.getTemplates()
                        } else {
                            this.$message.error(res)
                        }
                    })
                })
                .catch(() => {
                })
        },
        doNewTemplate() {
            this.$prompt('请输入模板名', '提示', {
                confirmButtonText: '添加',
                cancelButtonText: '取消'
            })
                .then(({ value }) => {
                    addTemplate(this.selectedScheme, value).then(res => {
                        console.log(res)
                        if (res.code == 200) {
                            this.$message.success(res.data)
                            this.getTemplates()
                        } else {
                            this.$message.error(res)
                        }
                    })
                })
                .catch(() => {
                })
        },
        getDataFromApi() {
            this.getDataScource()
            this.getTemplates()
        },
        getDataScource() {
            getDataScource().then(res => {
                if (res.code == 200) {
                    console.log(res)
                    this.dataSource = res.data
                    console.log(this.dataSource)
                } else {
                    this.$msgError(res)
                }
            })
        },
        getTemplates() {
            getTemplates().then(res => {
                console.log(res)
                if (res.code == 200) {
                    this.templates = res.data
                    console.log(this.templates)
                } else {
                    this.$msgError(res)
                }
            })
        },
        debug(data) {
            console.log(data)
            return "999"
        },
        addRoww() {
            this.addDataSourceForm.push({})
        },
        onCheck(_, { checkedNodes }) {
            let checkedData = []
            //把选择的所有字段加到集合
            checkedNodes.forEach(item => {
                if (item.debug === 'table') {
                    return checkedData.push(item)
                }
            })
            this.selectedTableData = checkedData
        },
        deleteRow(row) {
            let ind = this.addDataSourceForm.indexOf(row)
            if (ind > -1) {
                this.addDataSourceForm.splice(ind, 1)
            } else {
                console.log("ind==-1")
            }

        },
        onTabChange(e) {
            //刷新高度
            this.$nextTick(this.reComputContentHeight)
        },
        reComputContentHeight() {
            //重新计算高度
            this.dataSourceHeight = this.$el.querySelector('.data-source-preview').offsetHeight
            let formBtnHeight = this.$el.querySelector('.form-btn').offsetHeight
            this.addDataSourceHeight = this.$el.querySelector('.add-data-source').offsetHeight - formBtnHeight
            this.addDataSourceWidth = this.$el.querySelector('.add-datasource-form').offsetWidth
            console.log("dataSourceHeight", this.dataSourceHeight)
            console.log("addDataSourceHeight", this.addDataSourceHeight)
            console.log("addDataSourceWidth", this.addDataSourceWidth)
        },
        importFromResultSet() {
            this.importFromResultSetDialogVisible = true
        },
        copySelectSql() {
            copy(`SELECT
    t.TABLE_NAME AS table_name,
		t.TABLE_COMMENT AS table_comment,
    c.COLUMN_NAME AS column_name,
    c.DATA_TYPE AS column_type,
    c.COLUMN_COMMENT AS column_comment
FROM
    information_schema.tables AS t
JOIN
    information_schema.columns AS c
ON
    t.TABLE_NAME = c.TABLE_NAME and t.TABLE_SCHEMA = c.TABLE_SCHEMA
WHERE
    t.TABLE_SCHEMA = DATABASE();`)
            this.$message.success("已复制SQL语句")
        },
        namespaceList() {
            let arr = []
            //提取所有数据源名称
            this.dataSource.forEach(ds => {
                arr.push(ds.name)
            })
            return arr
        },
        dataSourceList(namespace) {
            let null_namespace = "%^$#@B"
            //null值处理
            if (!namespace) {
                namespace = null_namespace
            }
            //从缓存读取以提升性能
            if (this.databaseCached[namespace]) {
                return this.databaseCached[namespace]
            }
            //筛选数据源
            let datasource
            if (namespace != null_namespace) {
                datasource = this.dataSource.filter(ds => ds.name == namespace)
            } else {
                datasource = this.dataSource
            }
            //从数据源中获取所有数据库，添加到结果集
            let set = new Set()
            datasource.forEach(ds => {
                ds.children.forEach(db => {
                    set.add(db.name)
                })
            })
            //去重，添加缓存
            let arr = Array.from(set)
            this.databaseCached[namespace] = arr
            return arr
        },
        databaseList(namespaceName, datasourceName){
            console.log(namespaceName, datasourceName)
            
            let null_namespaceName = "%^$#@B"
            let null_datasourceName = "#$%@SDF";
            //null值处理
            if (!namespaceName) {
                namespaceName = null_namespaceName
            }
            if (!datasourceName) {
                datasourceName = null_datasourceName
            }
            //从缓存查询内容，以提升性能
            if (this.tableCached[namespaceName] && this.tableCached[namespaceName][datasourceName]) {
                return this.tableCached[namespaceName][datasourceName]
            }
            let datasource
            //过滤命名空间
            if (namespaceName != null_namespaceName) {
                datasource = this.dataSource.filter(ns => ns.name == namespaceName)
            } else {
                datasource = this.dataSource
            }
            //从命名空间中找数据源，这里变量命名有问题，但功能正常
            let database = []
            if (datasourceName != null_datasourceName) {
                datasource.forEach(ds => {
                    ds.children.forEach(db => {
                        if (db.name == datasourceName) {
                            database.push(db)
                        }
                    })
                })
            } else {
                datasource.forEach(ds => {
                    database.push(...ds.children)
                })
            }
            //将所有库的表添加到set中去重
            let set = new Set()
            database.forEach(db => {
                db.children.forEach(tb => {
                    set.add(tb.name)
                })
            })
            //设置缓存
            let arr = Array.from(set)
            if (this.tableCached[namespaceName]) {
                this.tableCached[namespaceName][datasourceName] = arr
            } else {
                this.tableCached[namespaceName] = []
                this.tableCached[namespaceName][datasourceName] = arr
            }

            return arr
        },
        importResultSetFromClipBoard() {
            navigator.clipboard.readText()
                .then(text => {
                    let rows = text.split(/\r?\n|\r/)
                    let arr = []
                    rows.forEach(row => {
                        let data = row.split("\t")
                        arr.push({
                            table: data[0],
                            table_comment: data[1],
                            column_name: data[2],
                            column_type: data[3],
                            column_comment: data[4]
                        })
                    })
                    this.importFromResultSetForm.resultSet = arr
                    console.log(arr)
                })
                .catch(err => {
                    console.error('无法读取剪切板内容: ', err);
                });
        },
        templateChange(selectedTemplate) {
            selectedTemplate.changed = true
        },
        changeTemplate(template) {
            // this.currentTemplateName = name
            // this.loadTemplate(name)
            this.selectedTemplate = null
            this.$nextTick(() => {
                this.selectedTemplate = template
                this.$nextTick(() => {
                    let el = this.$el.querySelector('.codemirror-container')
                    el.addEventListener('keydown', (e) => {
                        if (e.ctrlKey && e.key === 's') {
                            console.log("保存")
                            this.saveTemplate()
                            e.preventDefault()
                        }
                    })
                })
            })
        },
        saveTemplate() {
            let template = this.selectedTemplate
            saveTemplate(template).then(res => {
                console.log(res)
                template.changed = false
                if (res.code == 200) {
                    this.$message.success(res.data)
                } else {
                    this.$msgError(res)
                }
            })
        },
        tabInput(e) {
            e.preventDefault()
            const insertText = '\t'
            const elInput = e.target
            const startPos = elInput.selectionStart
            const endPos = elInput.selectionEnd
            if (startPos === undefined || endPos === undefined) return
            const txt = elInput.value
            elInput.value = txt.substring(0, startPos) + insertText + txt.substring(endPos)
            elInput.focus()
            elInput.selectionStart = startPos + insertText.length;
            elInput.selectionEnd = startPos + insertText.length;
            this.currentScheme.template = elInput.value
            this.templateChange()
        },
        onImportFromResult() {
            let form = this.$refs['importFromResultSetForm']
            form.validate((valid, fields) => {
                if (valid) {
                    let namespace = this.importFromResultSetForm.namespace
                    let datasource = this.importFromResultSetForm.datasource
                    let database = this.importFromResultSetForm.database
                    let arr = []
                    this.importFromResultSetForm.resultSet.forEach(row => {
                        arr.push({
                            table_name: row.table,
                            table_comment:row.table_comment,
                            column_name: row.column_name,
                            column_comment: row.column_comment,
                            sqlType: row.column_type
                        })
                    })
                    importDatasource(namespace,datasource,database,arr).then(res=>{
                        console.log(res)
                    })
                } else {
                    console.log('error submit!', fields)
                }
            })
        },
        releaseImport() {
            console.log(this.addDataSourceForm)
        },
        getJavaType(sqlType) {
            switch (sqlType) {
                case "varchar":
                    return "java.lang.String"
                case "date":
                case "datetime":
                    return "java.util.Date"
                case "int":
                    return "java.lang.Integer"
                case "bigint":
                    return "java.lang.String"
                case "tinyint":
                    return "java.lang.Boolean"
                default:
                    return "java.lang.String"
            }
        },
        createViewByTable(view, table) {
            let obj = table
            if (obj) {
                obj = Object.assign({}, obj)
                view.tb = {
                    name: obj.name,
                    columns: obj.children,
                    class_name: convertToCamelCase(obj.name, true),
                    comment: obj.comment
                }

                console.log(this.dataSource)

                obj.children.forEach(column => {
                    column.field_name = convertToCamelCase(column.name, false)
                    let javaType = this.getJavaType(column.sqlType)
                    column.java_short_type = javaType.split(".").at(-1)
                    column.java_full_type = javaType
                })
                let importPackage = new Set()
                obj.children.forEach(column => {
                    let javaType = column.java_full_type
                    if (!javaType.startsWith("java.lang.")) {
                        importPackage.add(javaType)
                    }
                })
                view.import_package = Array.from(importPackage)
            }
        },
        debugCurrentSchemeTemplate() {
            let view = {
            }
            this.createViewByTable(view, this.debugDataTable.at(-1))
            console.log(this.selectedTemplate)
            let res = render(this.selectedTemplate.content, view)
            this.$message({
                type: 'success',
                message: '调试结果打印在控制台',
                duration: 500
            })
            console.log(
                '%c %s',
                "border: 1px solid white;border-radius: 3px 0 0 3px;padding: 2px 5px;color: white;background-color: green;",
                "==========以下为调试结果=========="
            )
            console.log(res.res)
            console.log(
                '%c %s',
                "border: 1px solid white;border-radius: 3px 0 0 3px;padding: 2px 5px;color: white;background-color: green;",
                "==========以下为调试日志信息=========="
            )
            res.logs.forEach(item => {
                let bgc = "green"
                if (item.leave === 'error') {
                    bgc = 'red'
                }
                console.log(
                    '%c %s %c %s',
                    "border: 1px solid white;border-radius: 3px 0 0 3px;padding: 2px 5px;color: white;background-color: " + bgc + ";",
                    item.line ? `脚本第${item.line}行:` : "报错",
                    "",
                    item.str
                )
            })
        },
        generateFiles() {
            console.log(this.selectedTableData)
            console.log(this.checkedTemplate)
            if (!this.selectedTableData || !this.selectedTableData.length) {
                return null
            }
            if (!this.checkedTemplate || !this.checkedTemplate.length) {
                return null
            }
            return getDirContent(this.checkedTemplate)
        },
        onNodeClick(a, b, c) {
            if (a.content) {
                //预览内容
                console.log(a)
            }
        },
        downloadGenerateFile() {
            console.log(this.checkedTemplate, this.selectedTableData)

            let zip = createZip()
            let logs = []
            if (this.selectedTableData) {
                this.selectedTableData.forEach(table => {
                    let view = {}
                    this.createViewByTable(view, table)
                    this.checkedTemplate.forEach(template => {
                        let fileContent = getDirContent([template], view,logs)
                        createZip(zip, fileContent)
                    })
                })
            } else {
                let view = {}
                this.checkedTemplate.forEach(template => {
                    let fileContent = getDirContent([template], view,logs)
                    createZip(zip, fileContent)
                })
            }
            console.log(logs)
            // return
            zip.generateAsync({ type: "blob" }).then(function (base64) {
                var tmp = document.createElement('a');
                tmp.download = "test.zip";
                tmp.style.display = 'none';
                tmp.href = URL.createObjectURL(base64);
                document.body.appendChild(tmp);
                tmp.click();
                document.body.removeChild(tmp);
            });
        },
        transferFilesToTreeData(file, dirName) {
            let res = []
            for (let key in file) {
                let fileKey = dirName + "/" + key
                if (typeof file[key] === 'string') {
                    res.push({
                        name: key,
                        key: fileKey,
                        content: file[key]
                    })
                } else {
                    res.unshift({
                        name: key,
                        key: fileKey,
                        children: this.transferFilesToTreeData(file[key], fileKey)
                    })
                }
            }
            return res
            return [
                {
                    name: 'web',
                    children: [
                        {
                            name: 'controller',
                            children: [
                                {
                                    name: 'Main.java'
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    },
    mounted() {
        this.reComputContentHeight()
    },
    created() {
        this.getDataFromApi()
    },
    computed: {
        cascaderData() {
            if (this.dataSource === null) {
                return []
            }
            console.log(this.dataSource)
            let arr = []
            this.dataSource.forEach(ns => {
                let nameSpace = ns.name
                let dsArr = []
                arr.push({
                    children: dsArr,
                    label: nameSpace
                })
                ns.children.forEach(ds => {
                    let dsName = ds.name
                    let dbArr = []
                    dsArr.push({
                        children: dbArr,
                        label: dsName
                    })
                    ds.children.forEach(db => {
                        let dbName = db.name
                        let tbArr = []
                        dbArr.push({
                            children: tbArr,
                            label: dbName
                        })
                        db.children.forEach(tb => {
                            tbArr.push({
                                value: tb,
                                label: tb.name
                            })
                        })
                    })
                })
            })
            return arr
        },
        fodelTreeData() {
            let files = this.generateFiles()
            console.log(files)
            if (!files) {
                return []
            }
            let res = this.transferFilesToTreeData(files, "")
            console.log(res)
            return res
        }
    },
    components: {
        Codemirror
    }
}
</script>
<style lang="scss">
#dev-assistant {
    width: 100%;
    height: 100%;

    .el-tree-node__expand-icon.is-leaf {
        color: transparent;
    }

    .tabs {
        height: 100%;
        width: 100%;
        display: flex;
        flex-direction: column;

        .el-tabs__content {
            flex: 1;

            >div {
                width: 100%;
                height: 100%;
            }
        }
    }

    .add-data-source {
        .add-datasource-form {
            flex: 1;

            .header {
                color: var(--el-table-header-text-color);
                font-weight: 700;
                align-items: center;
            }

            .row {
                flex: 1;
                display: flex;

                >div {
                    flex: 1;
                    text-align: center;
                }
            }
        }

        .form-btn {
            padding: 10px 0;
        }
    }

    .data-source {
        height: 100%;
        display: flex;

        .data-source-list {
            width: 200px;
            box-shadow: 1px 0px 10px #ccc;
            margin-right: 10px;
        }

        .preview {
            // flex: 1;
            display: flex;
            flex-direction: column;
            width: 400px;

            >div {
                display: flex;
            }
        }

        .fodel_preview {
            flex: 1;
        }
    }

    .code-template {
        display: flex;
        flex-direction: column;
        height: 100%;

        .header {
            display: flex;
            gap: 15px;
            align-items: center;
            margin-left: 20px;
        }

        .content {
            display: flex;
            flex: 1;
            margin-top: 15px;

            .scheme {
                width: 20%;

                .templateItem {
                    cursor: pointer;
                }

                .selectedTemplate {
                    background-color: #ccc;
                }
            }

            .template {
                width: 60%;
                display: flex;
            }

            .tip {
                flex: 1;
            }
        }
    }
}
</style>